package org.jeecg.modules.third.digitalseal.utils;

import com.itextpdf.text.pdf.BaseFont;
import org.apache.commons.io.FileUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.hibernate.loader.collection.SubselectOneToManyLoader;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Description: PdfToImage
 * @author: luruirui
 * @date: 2021年04月15日 14:28
 */
public class PdfToImageUtil {
    /**
     * dpi越大转换后越清晰，相对转换速度越慢
     */
    private static final Integer DPI = 100;

    /**
     * 转换后的图片类型
     */
    private static final String IMG_TYPE = "jpg";

    /**
     * PDF转图片
     *
     * @param fileContent PDF文件的二进制流
     * @return 图片文件的二进制流
     */
    public static List<byte[]> pdfToImagHe(byte[] fileContent) throws IOException {
        List<byte[]> result = new ArrayList<>();
        try (PDDocument document = PDDocument.load(fileContent)) {
            PDFRenderer renderer = new PDFRenderer(document);
            for (int i = 0; i < document.getNumberOfPages(); ++i) {
                BufferedImage bufferedImage = renderer.renderImageWithDPI(i, DPI);
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                ImageIO.write(bufferedImage, IMG_TYPE, out);
                result.add(out.toByteArray());
            }
        }
        return result;
    }
    /**
     * 转换全部的pdf
     * @param fileAddress 文件地址
     * @param filename PDF文件名(去除后缀)
     * @return
     */
    public static List<String> pdf2Jpg(String fileAddress,String filename) throws IOException {
        // 将pdf装图片 并且自定义图片得格式大小
        File file = new File(fileAddress + filename + ".pdf");
        if (!file.exists()) {
            file.mkdirs();// 创建文件根目录
        }
        List<String> srcList = new ArrayList<>();//图片地址列表
        PDDocument doc = PDDocument.load(file);

        try {
            PDFRenderer renderer = new PDFRenderer(doc);
            int pageCount = doc.getNumberOfPages();
            for (int i = 0; i < pageCount; i++) {
                BufferedImage image = renderer.renderImageWithDPI(i, 144); // Windows native DPI
                // BufferedImage srcImage = resize(image, 240, 240);//产生缩略图
                String wholeFileName = filename + "_"+(i+1)+"."+IMG_TYPE;
                String imgPath = fileAddress + wholeFileName;
                ImageIO.write(image, IMG_TYPE, new File(imgPath));
                srcList.add(wholeFileName);
            }
        }  catch (IOException e) {
            e.printStackTrace();
        } finally {
            doc.close();
        }
        return srcList;
    }

    /**
     * 转换全部的pdf
     * @param fileAddress 文件地址
     * @param filename PDF文件名（去除后缀）
     * @param savePath 保存路径
     * @return
     */
    public static List<String> pdf2Jpg(String fileAddress, String filename, String savePath) {
        // 将pdf装图片 并且自定义图片得格式大小
        File file = new File(fileAddress + filename + ".pdf");
        List<String> srcList = new ArrayList<>();//图片地址列表
        try {
            PDDocument doc = PDDocument.load(file);
            PDFRenderer renderer = new PDFRenderer(doc);
            int pageCount = doc.getNumberOfPages();
            for (int i = 0; i < pageCount; i++) {
                BufferedImage image = renderer.renderImageWithDPI(i, 144); // Windows native DPI
                String wholeFileName = filename + "_"+(i+1)+"."+IMG_TYPE;
                String imgPath = (savePath != null ? savePath : fileAddress) + wholeFileName;
                ImageIO.write(image, IMG_TYPE, new File(imgPath));
                srcList.add(wholeFileName);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return srcList;
    }

    /**
     * 银行电子回单pdf转jpg
     * @param fileAddress 文件地址
     * @param filename PDF文件名（去除后缀）
     * @param savePath 保存路径
     * @return
     */
    public static String bankHdPdf2Jpg(String fileAddress, String filename, String savePath) {
        // 将pdf装图片 并且自定义图片得格式大小
        String pdfFileName = fileAddress + filename + ".pdf";
        String newPdfFileName = savePath + filename + ".pdf";
        File file = new File(pdfFileName);
        String newFileName = null;
        try {
            PDDocument doc = PDDocument.load(file);
            PDFRenderer renderer = new PDFRenderer(doc);
            //电子回单只有1页
//            int pageCount = doc.getNumberOfPages();
            BufferedImage image = renderer.renderImageWithDPI(0, 144); // Windows native DPI
            newFileName = filename + "." + IMG_TYPE;
            String imgPath = (savePath != null ? savePath : fileAddress) + newFileName;
            File fileImgPath = new File(imgPath);
            if (!fileImgPath.exists()) {
                fileImgPath.mkdirs();// 创建文件根目录
            }
            ImageIO.write(image, IMG_TYPE, fileImgPath);
            //移动pdf
            File pdfFile = new File(pdfFileName);
            File newPdfFile = new File(newPdfFileName);
            //先使用renameTo方法进行移动
            boolean rename =  pdfFile.renameTo(newPdfFile);
            if (!rename) {
                //renameTo移动失败，就复制文件，然后删除原文件
                FileUtils.copyFile( pdfFile, newPdfFile);
                if (!pdfFile.delete()) {
                    FileUtils.deleteQuietly(pdfFile);
                    throw new IOException("Failed to delete original file '" + pdfFile +"' after copy to '" + newPdfFile + "'");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return newFileName;
    }

    /**
     * 重新生成图片
     * @param fileAddress
     * @param filename
     * @param savePath
     * @return
     */
    public static String bankHdPdf2Jpg2(String fileAddress, String filename, String savePath) {

        String newFileName = null;
        // 将pdf装图片 并且自定义图片得格式大小
        String pdfFileName = fileAddress + filename + ".pdf";
        String newPdfFileName = savePath + filename + ".pdf";
        File file = new File(pdfFileName);
        if(!file.exists()){
            System.out.println("bankHdPdf2Jpg2 pdfFileName : "+pdfFileName);
            return newFileName;
        }
        try {
            PDDocument doc = PDDocument.load(file);
            PDFRenderer renderer = new PDFRenderer(doc);
            //电子回单只有1页
//            int pageCount = doc.getNumberOfPages();
            BufferedImage image = renderer.renderImageWithDPI(0, 144); // Windows native DPI
            newFileName = filename + "." + IMG_TYPE;
            String imgPath = (savePath != null ? savePath : fileAddress) + newFileName;
            File fileImgPath = new File(imgPath);
            if (!fileImgPath.exists()) {
                fileImgPath.mkdirs();// 创建文件根目录
            }
            ImageIO.write(image, IMG_TYPE, fileImgPath);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return newFileName;
    }


    /**
     * 图片转换成pdf
     * @param imageFile
     * @param outFile
     * @throws IOException
     */
    public static void imageToPdf(String imageFile, String outFile) throws IOException {

        try {
            File fileImage = new File(imageFile);
            File filePdf = new File(outFile);

            BufferedImage image = ImageIO.read(fileImage);

            PDDocument outDocument = new PDDocument();

            PDImageXObject imageXObject = LosslessFactory.createFromImage(outDocument, image);
            PDPage pdPage = new PDPage(PDRectangle.A4);
            outDocument.addPage(pdPage);
            PDPageContentStream pageContentStream = new PDPageContentStream(outDocument, pdPage);
            float height = pdPage.getMediaBox().getHeight();//要将图片在pdf中绘制多高，这里宽度直接使用了pdfpage的宽度，即横向铺满，这里的height也是使用了pdfpage的高度。因此最终结果是铺满整个pdf页。
            float y = pdPage.getMediaBox().getHeight() - height;//这里比较奇葩的是这个坐标是以左下角为原点坐标的。
            pageContentStream.drawImage(imageXObject, 0, y, pdPage.getMediaBox().getWidth(), height);
            pageContentStream.close();

            if (!filePdf.getParentFile().exists()) {
                filePdf.getParentFile().mkdirs();
            }

            outDocument.save(outFile);
            outDocument.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     *自由确定起始页和终止页
     * @param fileAddress 文件地址
     * @param filename pdf文件名
     * @param indexOfStart 开始页  开始转换的页码，从0开始
     * @param indexOfEnd 结束页  停止转换的页码，-1为全部
     * @param type 图片类型
     */
    public static void pdf2png(String fileAddress,String filename,int indexOfStart,int indexOfEnd,String type) {
        // 将pdf装图片 并且自定义图片得格式大小
        File file = new File(fileAddress+"\\"+filename+".pdf");
        try {
            PDDocument doc = PDDocument.load(file);
            PDFRenderer renderer = new PDFRenderer(doc);
            int pageCount = doc.getNumberOfPages();
            for (int i = indexOfStart; i < indexOfEnd; i++) {
                BufferedImage image = renderer.renderImageWithDPI(i, 144); // Windows native DPI
                // BufferedImage srcImage = resize(image, 240, 240);//产生缩略图
                ImageIO.write(image, type, new File(fileAddress+"\\"+filename+"_"+(i+1)+"."+type));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main( String[] args ){

        //System.out.println(
        //        bankHdPdf2Jpg2("C:\\Users\\Administrator\\Desktop\\fsdownload\\","CMRA76.15491101040044242_20230107_467850338_15304678503380689946","C:\\Users\\Administrator\\Desktop\\fsdownload\\")
        //);
//        List<String> srcList = pdf2Jpg("C:\\opt\\bank\\", "CMRA76.15491101040043467_20210520_259850201_15302598502015193702");
//        System.out.println(srcList);
    }
}
